/**
  ******************************************************************************
  * @file    delay_no_block.c
  * @author  ashuai0110
  * @version V2.4
  * @date    2024-09-10
  * @brief   非阻塞延时
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  * Change Logs:
  * Date          Author        Notes
  * 2023-10-27    ashuai0110    完成基本内容
  * 2023-12-28    ashuai0110    修改从组件计时节拍接口获取时基
  * 2024-09-02    ashuai0110    修改超时判断逻辑,删除一些assert
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "delay_no_block.h"

/**
 * @addtogroup modules
 * @{
 */

/**
 * @defgroup delay_no_block delay_no_block
 * @{
 */

/* 私有宏定义-----------------------------------------------------------------*/
/**
 * @defgroup delay_no_block_local_macros delay no block local macros
 * @{
 */

/**
 * @defgroup delay_no_block_check_parameters_validity delay no block check parameters validity
 * @{
 */
/* 延时任务ID有效性检查 */
#define IS_VALID_DELAY_ID(x)                                                  \
(       (x) <= DELAY_TASK_MAX)
/**
 * @}
 */

/**
 * @}
 */

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/
/**
 * @defgroup delay_no_block_local_variables delay no block local variables
 * @{
 */

static delay_item_t delayTaskArr[DELAY_TASK_MAX]; /*!< 延时任务数组 */

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/

/**
 * @defgroup delay_no_block_global_functions delay no block global functions
 * @{
 */

/**
  * @brief  创建延时任务
  *
  * @note   若创建的任务ID为局部变量则需要初始化值为0
  *
  * @param  _id        : 延时任务ID
  *
  * @param  delayTicks : 延时时间ms
  *
  * @retval 返回创建结果
  *    @arg MW_RET_OK  : 创建成功
  *    @arg MW_RET_ERR : 任务已满(创建失败)
  */
uint8_t delay_init(delay_id_t *_id, uint32_t delayTicks)
{
    delay_id_t idCnt;
    
    MW_ASSERT_PARAM(IS_VALID_DELAY_ID(*_id));
    
    /* id为0说明是新建任务 */
    if(0 == *_id)
    {
        /* 遍历任务数组 */
        for(idCnt = 0; idCnt < DELAY_TASK_MAX; idCnt++)
        {
            /* 若某个任务的计数值为0且运行标志为不运行则说明则任务为空 */
            if(0 == delayTaskArr[idCnt].ticks && 0 == delayTaskArr[idCnt].run)
            {
                /* 将延时参数存入空任务位置 */
                delayTaskArr[idCnt].ticks = delayTicks;
                delayTaskArr[idCnt].curTicks = mw_tick_get();
                delayTaskArr[idCnt].run = 1;
                *_id = idCnt + 1; /* 记录此任务 */
                
                break;
            }
        }
    } /* 不为0说明是旧任务更新延时时间 */
    else
    {
        delayTaskArr[*_id - 1].ticks = delayTicks;
        delayTaskArr[*_id - 1].curTicks = mw_tick_get();
        delayTaskArr[*_id - 1].run = 1;
    }
    
    return *_id ? MW_RET_OK : MW_RET_ERR;
}

/**
  * @brief  取消延时任务
  *
  * @param  _id : 延时任务ID
  *
  * @retval None
  */
void delay_de_init(delay_id_t *_id)
{
    /* 延时任务参数置零 id置零 */
    memset(&delayTaskArr[*_id - 1], 0, sizeof(delay_item_t));
    *_id = 0;
}

/**
  * @brief  等待延时任务返回完成
  *
  * @param  _id        : 延时任务ID
  *
  * @retval 返回结果
  *    @arg MW_RET_OK  : 延时完成
  *    @arg MW_RET_ERR : 无延时任务
  *    @arg MW_RET_ING : 延时进行中
  */
uint8_t delay_wait(delay_id_t *_id)
{
    /* 若某个任务的计数值为0且运行标志为不运行则说明则任务为空返回错误 */
    if(0 == delayTaskArr[*_id - 1].ticks || 0 == delayTaskArr[*_id - 1].run)
    {
        return MW_RET_ERR;
    }
    
    /* 计时计数值超出延时时间说明延时结束 清零计数值并返回完成 */
    if((mw_tick_get() - delayTaskArr[*_id - 1].curTicks) > delayTaskArr[*_id - 1].ticks)
    {
        delayTaskArr[*_id - 1].ticks = 0;
        
        return MW_RET_OK;
    }
    
    return MW_RET_ING;
}

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */
